package com.mangix.http;

import javax.servlet.AsyncContext;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;


/**
 * Created by Ahan on 2014/8/16.
 */
public class MangixObjectReadListener implements ReadListener {

    private HttpServletRequest req;
    private ServletInputStream input;
    private AsyncContext context;
    private OutputStream out;
    private byte[] buffer;
    private HttpURLConnection httpConn;

    public MangixObjectReadListener(ServletInputStream input, AsyncContext context, String hostname, int port, String key, int replicasNum, long contentLength) {
        this.input = input;
        this.context = context;
        this.buffer = new byte[1024];
        try {
            URL url = new URL("http://" + hostname + ":" + port + "/direct/objects/" + key);
            httpConn = (HttpURLConnection) url.openConnection();
            // The content length must be set!
            httpConn.setFixedLengthStreamingMode(contentLength);
            httpConn.setRequestProperty(MangixHttpHeader.CONTENT_LENGTH, contentLength + "");
            httpConn.setRequestProperty(MangixHttpHeader.REPLICAS_NUM, replicasNum + "");
//            httpConn.setRequestProperty("Content-Type", "application/octet-stream");
//            httpConn.setRequestProperty("Connection", "close");
            httpConn.setRequestMethod("PUT");
//            httpConn.setUseCaches(false);
            httpConn.setDoOutput(true);
            out = httpConn.getOutputStream();
        } catch (Exception e) {
            e.printStackTrace();
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
            HttpServletResponse resp = (HttpServletResponse)context.getResponse();
            try {
                resp.sendError(500, e.getMessage());
            } catch (IOException e1) {
                e1.printStackTrace();
            }
            try {
                input.close();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
            context.complete();
        }
    }

    @Override
    public void onDataAvailable() throws IOException {
        int len = -1;
        while (input.isReady() && (len = input.read(buffer)) != -1) {
            out.write(buffer, 0, len);
        }
    }

    @Override
    public void onAllDataRead() throws IOException {
        if (out != null) {
            out.close();
        }
        input.close();
        context.getResponse().getOutputStream().close();
        context.complete();
    }

    @Override
    public void onError(Throwable throwable) {
        throwable.printStackTrace();
        HttpServletResponse resp = (HttpServletResponse)context.getResponse();
        try {
            resp.sendError(500, throwable.getMessage());
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        try {
            input.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            context.getResponse().getOutputStream().close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        context.complete();
    }
}
